home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / winterp-1.13 / src-server / wc_SHELL.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-04  |  34.8 KB  |  853 lines

  1. /* -*-C-*-
  2. ********************************************************************************
  3. *
  4. * File:         wc_SHELL.c
  5. * RCS:          $Header: wc_SHELL.c,v 1.6 91/04/08 14:06:52 mayer Exp $
  6. * Description:  SHELL_WIDGET/POPUP_SHELL_WIDGET metaclass + class instances.
  7. * Author:       Niels Mayer, HPLabs
  8. * Created:      Fri Oct 27 22:03:22 1989
  9. * Modified:     Thu Oct  3 23:40:48 1991 (Niels Mayer) mayer@hplnpm
  10. * Language:     C
  11. * Package:      N/A
  12. * Status:       X11r5 contrib tape release
  13. *
  14. * WINTERP Copyright 1989, 1990, 1991 Hewlett-Packard Company (by Niels Mayer).
  15. * XLISP version 2.1, Copyright (c) 1989, by David Betz.
  16. *
  17. * Permission to use, copy, modify, distribute, and sell this software and its
  18. * documentation for any purpose is hereby granted without fee, provided that
  19. * the above copyright notice appear in all copies and that both that
  20. * copyright notice and this permission notice appear in supporting
  21. * documentation, and that the name of Hewlett-Packard and David Betz not be
  22. * used in advertising or publicity pertaining to distribution of the software
  23. * without specific, written prior permission.  Hewlett-Packard and David Betz
  24. * make no representations about the suitability of this software for any
  25. * purpose. It is provided "as is" without express or implied warranty.
  26. *
  27. * HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  28. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  29. * IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
  30. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  31. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  32. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  33. * PERFORMANCE OF THIS SOFTWARE.
  34. *
  35. * See ./winterp/COPYRIGHT for information on contacting the authors.
  36. * Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
  37. * Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
  38. *
  39. ********************************************************************************
  40. */
  41. static char rcs_identity[] = "@(#)$Header: wc_SHELL.c,v 1.6 91/04/08 14:06:52 mayer Exp $";
  42.  
  43. #include <stdio.h>
  44. #include <X11/Intrinsic.h>
  45. #include <X11/Shell.h>
  46. #include <Xm/Xm.h>
  47. #include <Xm/DialogS.h>
  48. #include <Xm/MenuShell.h>
  49.  
  50. #include "winterp.h"
  51.  
  52. /* this must come after winterp.h since WINTERP_MOTIF_11 may be def'd there */
  53. #ifdef WINTERP_MOTIF_11
  54. #include <Xm/Protocols.h>    /* <Xm/Protocols.h> location seems to have moved in 1.1 */
  55. #else
  56. #include <X11/Protocols.h>
  57. #endif                /* WINTERP_MOTIF_11 */
  58.  
  59. #include "user_prefs.h"
  60. #include "xlisp/xlisp.h"
  61. #include "w_funtab.h"
  62.  
  63.  
  64. extern Widget Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(); /* w_classes.c */
  65.  
  66.  
  67. typedef struct _ShellWidgetAssoc_Node {
  68.   LVAL                 widget_OBJ;
  69.   Widget             widget_ID;
  70.   struct _ShellWidgetAssoc_Node* next;
  71. } ShellWidgetAssoc_Node;
  72.  
  73. static ShellWidgetAssoc_Node* shell_widget_alist = NULL;
  74.  
  75.  
  76. /*****************************************************************************
  77.  * This removes the (widget_OBJ . widget_ID) association from shell_widget_alist
  78.  * when the shell widget gets destroyed. It is called from
  79.  * Wshl_Assoc_WidgetID_With_WIDGETOBJ() via XtAddCallback().
  80.  ****************************************************************************/
  81. static void Wshl_Widget_Destroy_CallbackProc(widgetID, client_data, call_data)
  82.      Widget    widgetID;
  83.      XtPointer client_data;    /* type is really the ShellWidgetAssoc_Node* to be destroyed */
  84.      XtPointer call_data;
  85. {
  86.   register ShellWidgetAssoc_Node* cur;
  87.   register ShellWidgetAssoc_Node* prev;
  88.   register ShellWidgetAssoc_Node* elt_to_destroy = (ShellWidgetAssoc_Node*) client_data;
  89.  
  90.   if (!shell_widget_alist)    /* ASSERT(shell_widget_alist!=NULL): something has gone awry if this callbackproc got called but shell_widget_alist is empty. */
  91.     xlfatal("Internal error 0 in Wshl_Widget_Destroy_CallbackProc().");
  92.  
  93.   prev = (ShellWidgetAssoc_Node*) NULL;
  94.   cur = shell_widget_alist;
  95.   while (cur && (cur != elt_to_destroy)) {
  96.     prev = cur;
  97.     cur = cur->next;
  98.   }
  99.   if (!prev) {            /* shell_widget_alist == cur == elt_to_destroy */
  100.     shell_widget_alist = shell_widget_alist->next; /* pop the first elt */
  101.     XtFree(cur);
  102.   }
  103.   else if (cur) {        /* cur == elt_to_destroy */
  104.     prev->next = cur->next;    /* remove cur from alist */
  105.     XtFree(cur);
  106.   }
  107.   else            /* ASSERT(cur!=NULL): something has gone awry if this callbackproc got called but can't find elt_to_destroy in shell_widget_alist. */
  108.     xlfatal("Internal error 1 in Wshl_Widget_Destroy_CallbackProc().");
  109. }
  110.  
  111.  
  112. /*****************************************************************************
  113.  * This associates a WIDGETOBJ with a WIDGETID and stores it on the assoc list
  114.  * shell_widget_alist. This routine is needed to set up data for
  115.  * Wshl_WidgetID_To_WIDGETOBJ().
  116.  ****************************************************************************/
  117. static void Wshl_Assoc_WidgetID_With_WIDGETOBJ(widget_id, o_widget)
  118.      Widget widget_id;
  119.      LVAL o_widget;
  120. {
  121.   ShellWidgetAssoc_Node* elt = (ShellWidgetAssoc_Node*) XtMalloc(sizeof(ShellWidgetAssoc_Node));
  122.   elt->widget_OBJ = o_widget;
  123.   elt->widget_ID  = widget_id;
  124.  
  125.   if (shell_widget_alist)
  126.     elt->next = shell_widget_alist;
  127.   else
  128.     elt->next = NULL;        /* elt is the only one on the alist */
  129.  
  130.   shell_widget_alist = elt;    /* make elt the new head of the list */
  131.  
  132.   XtAddCallback(widget_id, XmNdestroyCallback, Wshl_Widget_Destroy_CallbackProc, (XtPointer) elt); /* this removes elt when widget is destoyed */
  133. }
  134.  
  135.  
  136. /*****************************************************************************
  137.  * On all widgets other than shell widgets, we can retrieve the WIDGETOBJ
  138.  * associated with a particular Xt widget_id by retrieving the XmNuserData
  139.  * resource. Unfortunately, shell widgets do not have that resource, so we
  140.  * have to set up a special lookup mechanism. 
  141.  *
  142.  * Note: this routine uses a linear search through the association list 
  143.  * pointed at by shell_widget_alist. Since I don't expect applications to 
  144.  * have zillions of shell widgets, I think a linear search will be adequate.
  145.  ****************************************************************************/
  146. LVAL Wshl_WidgetID_To_WIDGETOBJ(widget_id)
  147.      Widget widget_id;
  148. {
  149.   extern void Wcls_Initialize_WIDGETOBJ(); /* w_classes.c */
  150.   extern LVAL Wcls_WidgetClassID_To_WIDGETCLASSOBJ(); /* w_classes.c */
  151.   extern LVAL o_WIDGET_CLASS;    /* from wc_WIDGET.c */
  152.   register ShellWidgetAssoc_Node* cur;
  153.   LVAL o_widgetclass, o_widget;
  154.  
  155.   /*
  156.    * first, try to find widgetobj corresponding to widget_id by doing a linear
  157.    * search on list created by Wshl_Assoc_WidgetID_With_WIDGETOBJ() returning
  158.    * that WIDGETOBJ if successful
  159.    */
  160.   cur = shell_widget_alist;
  161.   while (cur && (cur->widget_ID != widget_id))
  162.     cur = cur->next;
  163.   if (cur)            /* cur->widget_ID == widget_id */
  164.     return (cur->widget_OBJ);
  165.  
  166.   /*
  167.    * we couldn't find WIDGETOBJ associated with widget_id, so create a WIDGETOBJ
  168.    * of the appropriate class.
  169.    */
  170.   if (o_widgetclass = Wcls_WidgetClassID_To_WIDGETCLASSOBJ(XtClass(widget_id)))    /* returns NIL on failure */
  171.     o_widget = newobject(o_widgetclass, WIDGETOBJ_SIZE);
  172.   else {            /* fail gracefully (i think). */
  173.     errputstr("Warning -- In Wshl_WidgetID_To_WIDGETOBJ() couldn't find a valid\n");
  174.     errputstr("           widgetclass object inside widget classrecord. Creating\n");
  175.     errputstr("           a \"generic\" WIDGETOBJ of class WIDGET_CLASS.\n");
  176.     o_widget = newobject(o_WIDGET_CLASS, WIDGETOBJ_SIZE);
  177.   }
  178.   
  179.   Wcls_Initialize_WIDGETOBJ(o_widget, widget_id);
  180.   Wshl_Assoc_WidgetID_With_WIDGETOBJ(widget_id, o_widget);
  181.   return (o_widget);  
  182. }
  183.  
  184.  
  185.  
  186. /*****************************************************************************
  187.  * (send <Shell_Widget_Class> :new
  188.  *                                 [<name>]
  189.  *                   [<class-name>]
  190.  *                                 [:XMN_<arg1> <val1>]
  191.  *                                 [. . .             ]
  192.  *                                 [:XMN_<argN> <valN>])
  193.  *
  194.  * For the <Shell_Widget_Class> metaclass,
  195.  * create a new widget via XtAppCreateShell().
  196.  ****************************************************************************/
  197. LVAL Shell_Widget_Class_Method_ISNEW()
  198. {
  199.   extern ArgList Wres_Get_LispArglist(); /* from w_resources.c */
  200.   extern void    Wres_Free_C_Arglist_Data(); /* from w_resources.c */
  201.   extern WidgetClass Wcls_WIDGETCLASSOBJ_To_WidgetClassID(); /* w_classes.c */
  202.   extern Widget   toplevel_Wgt;    /* from winterp.c -- see "NOTE POTENTIAL BUG" comment below */
  203.   extern Display* display;    /* from winterp.c -- see "NOTE POTENTIAL BUG" comment below */
  204.   extern char*    app_class;    /* from winterp.c -- the class name of the application (defaults to "Winterp" unless given command-line -class <classname>) */
  205.   LVAL self;
  206.   char* name;
  207.   char* class_name;
  208.   WidgetClass widgetclass_id;
  209.   Widget widget_id;
  210.  
  211.   self = xlgaobject();        /* NOTE: xlobj.c:clnew() returns an OBJECT; if this method
  212.                    returns successfully, it will return a WIDGETOBJ */
  213.  
  214.   /* get optional <name> arg */
  215.   if (moreargs() && (stringp(*xlargv)))
  216.     name = (char*) getstring(nextarg());
  217.   else
  218.     name = "";            /* default name */
  219.  
  220.   /* get optional <class_name> arg */
  221.   if (moreargs() && (stringp(*xlargv)))
  222.     class_name = (char*) getstring(nextarg());
  223.   else
  224.     class_name = app_class;    /* default name */
  225.  
  226.   if (!(widgetclass_id = Wcls_WIDGETCLASSOBJ_To_WidgetClassID(getclass(self))))
  227.     xlerror("Expected a 'Class' object that is a subclass of 'WIDGET_CLASS'.", self);
  228.  
  229.   if (moreargs()) {        /* if there are more arguments, */
  230.     Cardinal xt_numargs;    /* then we have some extra widget resources to set */
  231.     ArgList xt_arglist = Wres_Get_LispArglist(self, toplevel_Wgt, NULL, 0, &xt_numargs);
  232.  
  233.     /* NOTE POTENTIAL BUG: above, we pass toplevel_Wgt as the widget for
  234.        Wres_Get_LispArglist(). toplevel_Wgt is created by XtInitialize() in
  235.        winterp.c:main(). Wres_Get_LispArglist() may need to use that widget
  236.        for particular kinds of argument conversions done through XtConvert().
  237.        These resource converters reference things like the display/screen/
  238.        foreground/background. For those cases, do not attempt to invoke
  239.        XtConvert() by passing string-valued arguments to this method. Instead,
  240.        create the shell widget, and then use :set_values to set the arguments
  241.        requiring such conversions. This will really break bigtime if I ever
  242.        implement multiple AppContexts for multiscreen usage of WINTERP.
  243.        
  244.        Note also that below, we pass the global "display" -- this will have
  245.        to change for multi-display use....*/
  246.  
  247.     widget_id = XtAppCreateShell(name, class_name, widgetclass_id, display, xt_arglist, xt_numargs);
  248.     Wres_Free_C_Arglist_Data();
  249.   }
  250.   else
  251.     widget_id = XtAppCreateShell(name, class_name, widgetclass_id, display, NULL, 0);
  252.  
  253.   Wcls_Initialize_WIDGETOBJ(self, widget_id);
  254.   Wshl_Assoc_WidgetID_With_WIDGETOBJ(widget_id, self);
  255.   
  256. #ifdef DEBUG_WINTERP_1
  257.   Wcls_Print_WidgetObj_Info(self);
  258. #endif
  259.   return (self);
  260. }
  261.  
  262. /*****************************************************************************
  263.  * (send APPLICATION_SHELL_WIDGET_CLASS :new
  264.  *                                 [<name>]
  265.  *                   [<class-name>]
  266.  *                                 [:XMN_<arg1> <val1>]
  267.  *                                 [. . .             ]
  268.  *                                 [:XMN_<argN> <valN>])
  269.  *
  270.  * For the APPLICATION_SHELL_WIDGET_CLASScreate a new widget via
  271.  * XtAppCreateShell().
  272.  *
  273.  * This is the same as the normal shell creation routine except that this
  274.  * overrides the application shell's delete response so that WINTERP is
  275.  * exited cleanly via wrapup().
  276.   ****************************************************************************/
  277. LVAL Application_Shell_Widget_Class_Method_ISNEW()
  278. {
  279.   extern ArgList Wres_Get_LispArglist(); /* from w_resources.c */
  280.   extern void    Wres_Free_C_Arglist_Data(); /* from w_resources.c */
  281.   extern WidgetClass Wcls_WIDGETCLASSOBJ_To_WidgetClassID(); /* w_classes.c */
  282.   extern Widget   toplevel_Wgt;    /* from winterp.c -- see "NOTE POTENTIAL BUG" comment below */
  283.   extern Display* display;    /* from winterp.c -- see "NOTE POTENTIAL BUG" comment below */
  284.   extern char*    app_class;    /* from winterp.c -- the class name of the application (defaults to "Winterp" unless given command-line -class <classname>) */
  285.   extern Atom     wm_delete_atom; /* from winterp.c */
  286.   extern void     Winterp_Application_Shell_WMDelete_Callback(); /* from winterp.c */
  287.   LVAL self;
  288.   char* name;
  289.   char* class_name;
  290.   WidgetClass widgetclass_id;
  291.   Widget widget_id;
  292.  
  293.   self = xlgaobject();        /* NOTE: xlobj.c:clnew() returns an OBJECT; if this method
  294.                    returns successfully, it will return a WIDGETOBJ */
  295.  
  296.   /* get optional <name> arg */
  297.   if (moreargs() && (stringp(*xlargv)))
  298.     name = (char*) getstring(nextarg());
  299.   else
  300.     name = "";            /* default name */
  301.  
  302.   /* get optional <class_name> arg */
  303.   if (moreargs() && (stringp(*xlargv)))
  304.     class_name = (char*) getstring(nextarg());
  305.   else
  306.     class_name = app_class;    /* default name */
  307.  
  308.   if (!(widgetclass_id = Wcls_WIDGETCLASSOBJ_To_WidgetClassID(getclass(self))))
  309.     xlerror("Expected a 'Class' object that is a subclass of 'WIDGET_CLASS'.", self);
  310.  
  311.   /*
  312.    * We handle wm deletion (f.kill) w/ XmAddWMProtocolCallback() below, therefore
  313.    * override the default delete-response of destroy...
  314.    */
  315.   ARGLIST_RESET(); ARGLIST_ADD(XmNdeleteResponse, XmDO_NOTHING);
  316.  
  317.   if (moreargs()) {        /* if there are more arguments, */
  318.     Cardinal xt_numargs;    /* then we have some extra widget resources to set */
  319.     ArgList xt_arglist = Wres_Get_LispArglist(self, toplevel_Wgt, ARGLIST(), &xt_numargs);
  320.  
  321.     /* NOTE POTENTIAL BUG: above, we pass toplevel_Wgt as the widget for
  322.        Wres_Get_LispArglist(). toplevel_Wgt is created by XtInitialize() in
  323.        winterp.c:main(). Wres_Get_LispArglist() may need to use that widget
  324.        for particular kinds of argument conversions done through XtConvert().
  325.        These resource converters reference things like the display/screen/
  326.        foreground/background. For those cases, do not attempt to invoke
  327.        XtConvert() by passing string-valued arguments to this method. Instead,
  328.        create the shell widget, and then use :set_values to set the arguments
  329.        requiring such conversions. This will really break bigtime if I ever
  330.        implement multiple AppContexts for multiscreen usage of WINTERP.
  331.        
  332.        Note also that below, we pass the global "display" -- this will have
  333.        to change for multi-display use....*/
  334.  
  335.     widget_id = XtAppCreateShell(name, class_name, widgetclass_id, display, xt_arglist, xt_numargs);
  336.     Wres_Free_C_Arglist_Data();
  337.   }
  338.   else
  339.     widget_id = XtAppCreateShell(name, class_name, widgetclass_id, display, ARGLIST());
  340.  
  341.   XmAddWMProtocolCallback(widget_id, wm_delete_atom, Winterp_Application_Shell_WMDelete_Callback, NULL);
  342.  
  343.   Wcls_Initialize_WIDGETOBJ(self, widget_id);
  344.   Wshl_Assoc_WidgetID_With_WIDGETOBJ(widget_id, self);
  345.   
  346. #ifdef DEBUG_WINTERP_1
  347.   Wcls_Print_WidgetObj_Info(self);
  348. #endif
  349.   return (self);
  350. }
  351.  
  352.  
  353. /*****************************************************************************
  354.  * (send <Popup_Shell_Widget_Class> :new
  355.  *                                       [<name>]
  356.  *                                       <parent> 
  357.  *                                       [:XMN_<arg1> <val1>]
  358.  *                                       [. . .             ]
  359.  *                                       [:XMN_<argN> <valN>])
  360.  *
  361.  * For the <Popup_Shell_Widget_Class> meta-class,
  362.  * create a new widget via XtCreatePopupShell().
  363.  ****************************************************************************/
  364. LVAL Popup_Shell_Widget_Class_Method_ISNEW()
  365. {
  366.   extern ArgList Wres_Get_LispArglist(); /* from w_resources.c */
  367.   extern void    Wres_Free_C_Arglist_Data(); /* from w_resources.c */
  368.   extern WidgetClass Wcls_WIDGETCLASSOBJ_To_WidgetClassID(); /* w_classes.c */
  369.   LVAL self;
  370.   LVAL o_parent;
  371.   char* name;
  372.   WidgetClass widgetclass_id;
  373.   Widget parent_widget_id, widget_id;
  374.  
  375.   self = xlgaobject();        /* NOTE: xlobj.c:clnew() returns an OBJECT; if this method
  376.                    returns successfully, it will return a WIDGETOBJ */
  377.  
  378.   /* get optional <name> arg */
  379.   if (moreargs() && (stringp(*xlargv)))
  380.     name = (char*) getstring(nextarg());
  381.   else
  382.     name = "";            /* default name */
  383.  
  384.   /* get required <parent> widget-object arg */
  385.   parent_widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&o_parent);
  386.  
  387.   if (!(widgetclass_id = Wcls_WIDGETCLASSOBJ_To_WidgetClassID(getclass(self))))
  388.     xlerror("Expected a 'Class' object that is a subclass of 'WIDGET_CLASS'.", self);
  389.  
  390.   if (moreargs()) {        /* if there are more arguments, */
  391.     Cardinal xt_numargs;    /* then we have some extra widget resources to set */
  392.     ArgList xt_arglist = Wres_Get_LispArglist(self, parent_widget_id, NULL, 0, &xt_numargs);
  393.     widget_id = XtCreatePopupShell(name, widgetclass_id, parent_widget_id, xt_arglist, xt_numargs);
  394.     Wres_Free_C_Arglist_Data();
  395.   }
  396.   else
  397.     widget_id = XtCreatePopupShell(name, widgetclass_id, parent_widget_id, NULL, 0);
  398.  
  399.   Wcls_Initialize_WIDGETOBJ(self, widget_id);
  400.   Wshl_Assoc_WidgetID_With_WIDGETOBJ(widget_id, self);
  401.  
  402. #ifdef DEBUG_WINTERP_1
  403.   Wcls_Print_WidgetObj_Info(self);
  404. #endif
  405.   return (self);
  406. }
  407.  
  408.  
  409. /*****************************************************************************
  410.  * (send <Popup_Shell_Widget_Instance> :popup <grabkind>)
  411.  * where <grabkind> is one of the following keyword symbols: 
  412.  *                  :grab_none, :grab_nonexclusive, or  :grab_exclusive.
  413.  ****************************************************************************/
  414. static LVAL k_grab_none;    /* initialized in Wc_SHELL_Init() */
  415. static LVAL k_grab_nonexclusive; /* initialized in Wc_SHELL_Init() */
  416. static LVAL k_grab_exclusive;    /* initialized in Wc_SHELL_Init() */
  417. LVAL Popup_Shell_Widget_Class_Method_POPUP()
  418. {
  419.   LVAL self, grabkind;
  420.   Widget widget_id;
  421.  
  422.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  423.   grabkind = xlgasymbol();
  424.   xllastarg();
  425.  
  426.   if (grabkind == k_grab_none)
  427.     XtPopup(widget_id, XtGrabNone);
  428.   else if (grabkind == k_grab_nonexclusive)
  429.     XtPopup(widget_id, XtGrabNonexclusive);
  430.   else if (grabkind == k_grab_exclusive)
  431.     XtPopup(widget_id, XtGrabExclusive);
  432.   else
  433.     xlerror("Unknown <grabkind> symbol. (Expected :grab_none, :grab_nonexclusive, or  :grab_exclusive)", grabkind);
  434.  
  435.   return (self);
  436. }
  437.  
  438.  
  439. /*****************************************************************************
  440.  * (send <Popup_Shell_Widget_Instance> :popdown)
  441.  ****************************************************************************/
  442. LVAL Popup_Shell_Widget_Class_Method_POPDOWN()
  443. {
  444.   LVAL self;
  445.   Widget widget_id;
  446.  
  447.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  448.   xllastarg();
  449.   
  450.   XtPopdown(widget_id);
  451.   return (self);
  452. }
  453.  
  454.  
  455. /*****************************************************************************
  456.  * (send <Shell_Widget_Instance> :realize)
  457.  ****************************************************************************/
  458. LVAL Shell_Widget_Class_Method_REALIZE()
  459. {
  460.   LVAL self;
  461.   Widget widget_id;
  462.  
  463.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  464.   xllastarg();
  465.  
  466.   XtRealizeWidget(widget_id);
  467.   return (self);
  468. }
  469.  
  470.  
  471. /*****************************************************************************
  472.  * (send <Shell_Widget_Instance> :unrealize)
  473.  ****************************************************************************/
  474. LVAL Shell_Widget_Class_Method_UNREALIZE()
  475. {
  476.   LVAL self;
  477.   Widget widget_id;
  478.  
  479.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  480.   xllastarg();
  481.  
  482.   XtUnrealizeWidget(widget_id);
  483.   return (self);
  484. }
  485.  
  486.  
  487. /******************************************************************************
  488.  * (send <Shell_Widget_Instance> :IS_MOTIF_WM_RUNNING)
  489.  * returns T if mwm is running, else NIL.
  490.  *
  491.  * extern Boolean XmIsMotifWMRunning(shell);
  492.  *        Widget shell;
  493.  *******************************************************************************/
  494. LVAL Shell_Widget_Class_Method_IS_MOTIF_WM_RUNNING()
  495. {
  496.   extern LVAL true;
  497.   LVAL self;
  498.   Widget widget_id;
  499.  
  500.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  501.   xllastarg();
  502.  
  503.   return (XmIsMotifWMRunning(widget_id) ? true : NIL);
  504. }
  505.  
  506. /******************************************************************************
  507.  * (send <Application_Shell_Widget_Instance> :GET_ARGV)
  508.  *     ==> returns an array of strings.
  509.  *
  510.  * This retrieves the resources XmNargv and XmNargc from <Application_Shell_Widget_Instance>
  511.  * and returns an array of strings representing the command line args with
  512.  * which the program was called.
  513.  *******************************************************************************/
  514. LVAL Application_Shell_Widget_Class_Method_GET_ARGV()
  515. {
  516.   LVAL self, result;
  517.   Widget widget_id;
  518.   String* retrieved_argv;
  519.   int     retrieved_argc, i;
  520.  
  521.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self); /* get <Application_Shell_Widget_Instance>  */
  522.   xllastarg();
  523.  
  524.   ARGLIST_RESET();
  525.   ARGLIST_ADD(XmNargc, &retrieved_argc);
  526.   ARGLIST_ADD(XmNargv, &retrieved_argv);
  527.   XtGetValues(widget_id, ARGLIST());
  528.  
  529.   if (retrieved_argc == 0)
  530.     return (NIL);
  531.   if (retrieved_argv == NULL)
  532.     return (NIL);
  533.   
  534.   xlsave1(result);
  535.  
  536.   result = newvector(retrieved_argc);
  537.  
  538.   for (i = 0; i < retrieved_argc; i++)
  539.     setelement(result, i, cvstring(retrieved_argv[i]));    /* cvstring() copies the string. This copy may be freed later via garbage collection. */
  540.  
  541.   xlpop();
  542.   return (result);
  543. }
  544.  
  545.  
  546. /******************************************************************************
  547.  * (send <Application_Shell_Widget_Instance> :SET_ARGV <args>)
  548.  * returns <Application_Shell_Widget_Instance>.
  549.  *
  550.  * This sets the XmNargv and XmNargc resources based on the sequence of string
  551.  * arguments <args>. The resources are set on <Application_Shell_Widget_Instance> 
  552.  * and this supposedly will allow session managers that the application should
  553.  * start up with the new <args> specified here.
  554.  *******************************************************************************/
  555. #define STRINGTABLE_SIZE_INCREMENT 20
  556. LVAL Application_Shell_Widget_Class_Method_SET_ARGV()
  557. {
  558.   LVAL self, lval_args, elt;
  559.   Widget widget_id;
  560.   String string_from_lisp, string_to_c;
  561.   int     string_length, i;
  562.   String* set_argv = NULL;
  563.   int     set_argc = 0;
  564.  
  565.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self); /* get <Application_Shell_Widget_Instance>  */
  566.   lval_args = xlgetarg();    /* get <args> */
  567.   xllastarg();
  568.  
  569.   /*
  570.    * if argument is a vector, then step through array of lisp <string>.
  571.    */
  572.   if (vectorp(lval_args)) {
  573.     set_argc = getsize(lval_args);
  574.     set_argv = (String*) XtMalloc((unsigned) ((set_argc + 1) * sizeof(String)));
  575.  
  576.     for (i = 0 ; i < set_argc ; i++) {
  577.       elt = getelement(lval_args, i);
  578.       if (stringp(elt)) {
  579.     if (string_from_lisp = (String) getstring(elt)) {
  580.       string_length = getslength(elt);
  581.       string_to_c = (String) XtMalloc((unsigned) (string_length + 1) * sizeof(char)); /* unpluggable memory leak -- XmNargv doesn't get copied in widget... */
  582.       string_to_c = strncpy(string_to_c, string_from_lisp, string_length);
  583.       string_to_c[string_length] = '\000';
  584.       set_argv[i] = string_to_c;
  585.     }
  586.     else
  587.       set_argv[i] = "";
  588.       }
  589.       else {
  590.     XtFree(set_argv);
  591.     xlerror("Expected as argument a sequence (list or vector) of strings; encountered a non-string array element.", elt);
  592.       }
  593.     }
  594.     set_argv[i] = NULL;        /* null terminate */
  595.     /* implicit: set_argc = i; */
  596.   }
  597.   /*
  598.    * if argument is a list, then cdr through list of lisp <string>
  599.    */
  600.   else if (consp(lval_args)) {
  601.     int size = STRINGTABLE_SIZE_INCREMENT;
  602.     set_argv = (String*) XtMalloc((unsigned) ((size + 1) * sizeof(String)));
  603.  
  604.     for (i = 0 ; (consp(lval_args)) ; lval_args = cdr(lval_args), i++) {
  605.       if (i >= size) {        /* make sure it'll fit into allocated set_argv */
  606.     size += STRINGTABLE_SIZE_INCREMENT;
  607.     set_argv = (String*) XtRealloc(set_argv, (unsigned) ((size + 1) * sizeof(String)));
  608.       }
  609.       elt = car(lval_args);
  610.       if (stringp(elt)) {
  611.     if (string_from_lisp = (String) getstring(elt)) {
  612.       string_length = strlen(string_from_lisp);
  613.       string_to_c = (String) XtMalloc((unsigned) (string_length + 1) * sizeof(char)); /* unpluggable memory leak -- XmNargv doesn't get copied in widget... */
  614.       string_to_c = strncpy(string_to_c, string_from_lisp, string_length);
  615.       string_to_c[string_length] = '\000';
  616.       set_argv[i] = string_to_c;
  617.     }
  618.     else
  619.       set_argv[i] = "";
  620.       }
  621.       else {
  622.     XtFree(set_argv);
  623.     xlerror("Expected as argument a sequence (list or vector) of strings; encountered a non-string list element.", elt);
  624.       }
  625.     }
  626.  
  627.     if (lval_args) {        /* if loop terminated due to list pointer not being a CONS cell */
  628.       XtFree(set_argv);
  629.       xlerror("Expected as argument a sequence (list or vector) of strings; encountered a weird list tail.", lval_args);
  630.     }
  631.  
  632.     set_argv[i] = NULL;        /* null terminate */
  633.     set_argc = i;
  634.   }
  635.   /*
  636.    * if argument wasn't list or vector, then error
  637.    */
  638.   else
  639.     xlerror("Wrong argument type given; Expected as argument a sequence (list or vector) of strings." , lval_args);
  640.  
  641.   ARGLIST_RESET();
  642.   ARGLIST_ADD(XmNargc, (XtArgVal) set_argc);
  643.   ARGLIST_ADD(XmNargv, (XtArgVal) set_argv);
  644.   XtSetValues(widget_id, ARGLIST());
  645.  
  646.   /*
  647.    * Normally, we'd want to free set_argv after passing it to the widget via XtSetValues().
  648.    * However, Motif/Xt has a bug in that if you free argv before XtRealize() gets called
  649.    * you'll get a core dump. Therefore, I don't free argv. On the other hand, this
  650.    * definitely causes a memory leak, but the fault lies in the Xtoolkit and Motif.
  651.    */
  652. #ifdef THE_FOLLOWING_CODE_IS_COMMENTED_OUT
  653.   if (set_argv)
  654.     XtFree(set_argv);
  655. #endif                /* THE_FOLLOWING_CODE_IS_COMMENTED_OUT */
  656.  
  657.  
  658.   return (self);
  659. }
  660.  
  661.  
  662.  
  663. /******************************************************************************
  664.  *
  665.  ******************************************************************************/
  666. Wc_SHELL_Init()
  667. {
  668.   LVAL o_TOP_LEVEL_SHELL_WIDGET_CLASS;
  669.   LVAL o_TOP_LEVEL_POPUP_SHELL_WIDGET_CLASS;
  670.   LVAL o_APPLICATION_SHELL_WIDGET_CLASS;
  671.   LVAL o_APPLICATION_POPUP_SHELL_WIDGET_CLASS;
  672.   LVAL o_OVERRIDE_SHELL_WIDGET_CLASS;
  673.   LVAL o_OVERRIDE_POPUP_SHELL_WIDGET_CLASS;
  674.   LVAL o_TRANSIENT_SHELL_WIDGET_CLASS;
  675.   LVAL o_TRANSIENT_POPUP_SHELL_WIDGET_CLASS;
  676.   LVAL o_XM_DIALOG_POPUP_SHELL_WIDGET_CLASS;
  677.   LVAL o_XM_MENU_POPUP_SHELL_WIDGET_CLASS;
  678.   extern LVAL Wcls_Create_Subclass_Of_WIDGET_CLASS(); /* w_classes.c */
  679.   extern      xladdmsg();    /* from xlobj.c */
  680.  
  681.   k_grab_none          = xlenter(":GRAB_NONE");
  682.   k_grab_nonexclusive  = xlenter(":GRAB_NONEXCLUSIVE");
  683.   k_grab_exclusive     = xlenter(":GRAB_EXCLUSIVE");
  684.  
  685.   /*------------------- TOP_LEVEL_SHELL_WIDGET_CLASS -----------------------*/
  686.   o_TOP_LEVEL_SHELL_WIDGET_CLASS = 
  687.     Wcls_Create_Subclass_Of_WIDGET_CLASS("TOP_LEVEL_SHELL_WIDGET_CLASS",
  688.                      topLevelShellWidgetClass);
  689.   xladdmsg(o_TOP_LEVEL_SHELL_WIDGET_CLASS, ":IS_MOTIF_WM_RUNNING", 
  690.        FTAB_Shell_Widget_Class_Method_IS_MOTIF_WM_RUNNING);
  691.   xladdmsg(o_TOP_LEVEL_SHELL_WIDGET_CLASS, ":UNREALIZE", 
  692.        FTAB_Shell_Widget_Class_Method_UNREALIZE);
  693.   xladdmsg(o_TOP_LEVEL_SHELL_WIDGET_CLASS, ":ISNEW", 
  694.        FTAB_Shell_Widget_Class_Method_ISNEW);
  695.   xladdmsg(o_TOP_LEVEL_SHELL_WIDGET_CLASS, ":REALIZE", 
  696.        FTAB_Shell_Widget_Class_Method_REALIZE);
  697.  
  698.   /*------------------- TOP_LEVEL_POPUP_SHELL_WIDGET_CLASS ------------------*/
  699.   o_TOP_LEVEL_POPUP_SHELL_WIDGET_CLASS = 
  700.     Wcls_Create_Subclass_Of_WIDGET_CLASS("TOP_LEVEL_POPUP_SHELL_WIDGET_CLASS",
  701.                      topLevelShellWidgetClass);
  702.  
  703.   xladdmsg(o_TOP_LEVEL_POPUP_SHELL_WIDGET_CLASS, ":IS_MOTIF_WM_RUNNING", 
  704.        FTAB_Shell_Widget_Class_Method_IS_MOTIF_WM_RUNNING);
  705.   xladdmsg(o_TOP_LEVEL_POPUP_SHELL_WIDGET_CLASS, ":UNREALIZE", 
  706.        FTAB_Shell_Widget_Class_Method_UNREALIZE);
  707.   xladdmsg(o_TOP_LEVEL_POPUP_SHELL_WIDGET_CLASS, ":POPUP",
  708.        FTAB_Popup_Shell_Widget_Class_Method_POPUP);
  709.   xladdmsg(o_TOP_LEVEL_POPUP_SHELL_WIDGET_CLASS, ":POPDOWN",
  710.        FTAB_Popup_Shell_Widget_Class_Method_POPDOWN);
  711.   xladdmsg(o_TOP_LEVEL_POPUP_SHELL_WIDGET_CLASS, ":ISNEW", 
  712.        FTAB_Popup_Shell_Widget_Class_Method_ISNEW);
  713.   xladdmsg(o_TOP_LEVEL_POPUP_SHELL_WIDGET_CLASS, ":REALIZE", 
  714.        FTAB_Shell_Widget_Class_Method_REALIZE);
  715.  
  716.   /*------------------- APPLICATION_SHELL_WIDGET_CLASS -----------------------*/
  717.   o_APPLICATION_SHELL_WIDGET_CLASS = 
  718.     Wcls_Create_Subclass_Of_WIDGET_CLASS("APPLICATION_SHELL_WIDGET_CLASS",
  719.                      applicationShellWidgetClass);
  720.   xladdmsg(o_APPLICATION_SHELL_WIDGET_CLASS, ":GET_ARGV", 
  721.        FTAB_Application_Shell_Widget_Class_Method_GET_ARGV);
  722.   xladdmsg(o_APPLICATION_SHELL_WIDGET_CLASS, ":SET_ARGV", 
  723.        FTAB_Application_Shell_Widget_Class_Method_SET_ARGV);
  724.   xladdmsg(o_APPLICATION_SHELL_WIDGET_CLASS, ":IS_MOTIF_WM_RUNNING", 
  725.        FTAB_Shell_Widget_Class_Method_IS_MOTIF_WM_RUNNING);
  726.   xladdmsg(o_APPLICATION_SHELL_WIDGET_CLASS, ":UNREALIZE", 
  727.        FTAB_Shell_Widget_Class_Method_UNREALIZE);
  728.   /*
  729.    * note special initializer method which sets up f.kill handler
  730.    * so that WINTERP exits cleanly.
  731.    */
  732.   xladdmsg(o_APPLICATION_SHELL_WIDGET_CLASS, ":ISNEW", 
  733.        FTAB_Application_Shell_Widget_Class_Method_ISNEW); 
  734.   xladdmsg(o_APPLICATION_SHELL_WIDGET_CLASS, ":REALIZE", 
  735.        FTAB_Shell_Widget_Class_Method_REALIZE);
  736.  
  737.   /*------------------- APPLICATION_POPUP_SHELL_WIDGET_CLASS -----------------------*/
  738.   o_APPLICATION_POPUP_SHELL_WIDGET_CLASS = 
  739.     Wcls_Create_Subclass_Of_WIDGET_CLASS("APPLICATION_POPUP_SHELL_WIDGET_CLASS",
  740.                      applicationShellWidgetClass);
  741.   xladdmsg(o_APPLICATION_POPUP_SHELL_WIDGET_CLASS, ":GET_ARGV", 
  742.        FTAB_Application_Shell_Widget_Class_Method_GET_ARGV);
  743.   xladdmsg(o_APPLICATION_POPUP_SHELL_WIDGET_CLASS, ":SET_ARGV", 
  744.        FTAB_Application_Shell_Widget_Class_Method_SET_ARGV);
  745.   xladdmsg(o_APPLICATION_POPUP_SHELL_WIDGET_CLASS, ":IS_MOTIF_WM_RUNNING", 
  746.        FTAB_Shell_Widget_Class_Method_IS_MOTIF_WM_RUNNING);
  747.   xladdmsg(o_APPLICATION_POPUP_SHELL_WIDGET_CLASS, ":UNREALIZE", 
  748.        FTAB_Shell_Widget_Class_Method_UNREALIZE);
  749.   xladdmsg(o_APPLICATION_POPUP_SHELL_WIDGET_CLASS, ":POPUP",
  750.        FTAB_Popup_Shell_Widget_Class_Method_POPUP);
  751.   xladdmsg(o_APPLICATION_POPUP_SHELL_WIDGET_CLASS, ":POPDOWN",
  752.        FTAB_Popup_Shell_Widget_Class_Method_POPDOWN);
  753.   xladdmsg(o_APPLICATION_POPUP_SHELL_WIDGET_CLASS, ":ISNEW", 
  754.        FTAB_Popup_Shell_Widget_Class_Method_ISNEW);
  755.   xladdmsg(o_APPLICATION_POPUP_SHELL_WIDGET_CLASS, ":REALIZE", 
  756.        FTAB_Shell_Widget_Class_Method_REALIZE);
  757.  
  758.   /*------------------- OVERRIDE_SHELL_WIDGET_CLASS -----------------------*/
  759.   o_OVERRIDE_SHELL_WIDGET_CLASS = 
  760.     Wcls_Create_Subclass_Of_WIDGET_CLASS("OVERRIDE_SHELL_WIDGET_CLASS",
  761.                      overrideShellWidgetClass);
  762.   xladdmsg(o_OVERRIDE_SHELL_WIDGET_CLASS, ":IS_MOTIF_WM_RUNNING", 
  763.        FTAB_Shell_Widget_Class_Method_IS_MOTIF_WM_RUNNING);
  764.   xladdmsg(o_OVERRIDE_SHELL_WIDGET_CLASS, ":UNREALIZE", 
  765.        FTAB_Shell_Widget_Class_Method_UNREALIZE);
  766.   xladdmsg(o_OVERRIDE_SHELL_WIDGET_CLASS, ":ISNEW", 
  767.        FTAB_Shell_Widget_Class_Method_ISNEW);
  768.   xladdmsg(o_OVERRIDE_SHELL_WIDGET_CLASS, ":REALIZE", 
  769.        FTAB_Shell_Widget_Class_Method_REALIZE);
  770.  
  771.   /*------------------- OVERRIDE_POPUP_SHELL_WIDGET_CLASS -----------------------*/
  772.   o_OVERRIDE_POPUP_SHELL_WIDGET_CLASS = 
  773.     Wcls_Create_Subclass_Of_WIDGET_CLASS("OVERRIDE_POPUP_SHELL_WIDGET_CLASS",
  774.                      overrideShellWidgetClass);
  775.   xladdmsg(o_OVERRIDE_POPUP_SHELL_WIDGET_CLASS, ":IS_MOTIF_WM_RUNNING", 
  776.        FTAB_Shell_Widget_Class_Method_IS_MOTIF_WM_RUNNING);
  777.   xladdmsg(o_OVERRIDE_POPUP_SHELL_WIDGET_CLASS, ":UNREALIZE", 
  778.        FTAB_Shell_Widget_Class_Method_UNREALIZE);
  779.   xladdmsg(o_OVERRIDE_POPUP_SHELL_WIDGET_CLASS, ":POPUP",
  780.        FTAB_Popup_Shell_Widget_Class_Method_POPUP);
  781.   xladdmsg(o_OVERRIDE_POPUP_SHELL_WIDGET_CLASS, ":POPDOWN",
  782.        FTAB_Popup_Shell_Widget_Class_Method_POPDOWN);
  783.   xladdmsg(o_OVERRIDE_POPUP_SHELL_WIDGET_CLASS, ":ISNEW", 
  784.        FTAB_Popup_Shell_Widget_Class_Method_ISNEW);
  785.   xladdmsg(o_OVERRIDE_POPUP_SHELL_WIDGET_CLASS, ":REALIZE", 
  786.        FTAB_Shell_Widget_Class_Method_REALIZE);
  787.  
  788.   /*------------------- TRANSIENT_SHELL_WIDGET_CLASS -----------------------*/
  789.   o_TRANSIENT_SHELL_WIDGET_CLASS = 
  790.     Wcls_Create_Subclass_Of_WIDGET_CLASS("TRANSIENT_SHELL_WIDGET_CLASS",
  791.                      transientShellWidgetClass);
  792.   xladdmsg(o_TRANSIENT_SHELL_WIDGET_CLASS, ":IS_MOTIF_WM_RUNNING", 
  793.        FTAB_Shell_Widget_Class_Method_IS_MOTIF_WM_RUNNING);
  794.   xladdmsg(o_TRANSIENT_SHELL_WIDGET_CLASS, ":UNREALIZE", 
  795.        FTAB_Shell_Widget_Class_Method_UNREALIZE);
  796.   xladdmsg(o_TRANSIENT_SHELL_WIDGET_CLASS, ":ISNEW", 
  797.        FTAB_Shell_Widget_Class_Method_ISNEW);
  798.   xladdmsg(o_TRANSIENT_SHELL_WIDGET_CLASS, ":REALIZE", 
  799.        FTAB_Shell_Widget_Class_Method_REALIZE);
  800.  
  801.   /*------------------- TRANSIENT_POPUP_SHELL_WIDGET_CLASS -----------------------*/
  802.   o_TRANSIENT_POPUP_SHELL_WIDGET_CLASS = 
  803.     Wcls_Create_Subclass_Of_WIDGET_CLASS("TRANSIENT_POPUP_SHELL_WIDGET_CLASS",
  804.                      transientShellWidgetClass);
  805.   xladdmsg(o_TRANSIENT_POPUP_SHELL_WIDGET_CLASS, ":IS_MOTIF_WM_RUNNING", 
  806.        FTAB_Shell_Widget_Class_Method_IS_MOTIF_WM_RUNNING);
  807.   xladdmsg(o_TRANSIENT_POPUP_SHELL_WIDGET_CLASS, ":UNREALIZE", 
  808.        FTAB_Shell_Widget_Class_Method_UNREALIZE);
  809.   xladdmsg(o_TRANSIENT_POPUP_SHELL_WIDGET_CLASS, ":POPUP",
  810.        FTAB_Popup_Shell_Widget_Class_Method_POPUP);
  811.   xladdmsg(o_TRANSIENT_POPUP_SHELL_WIDGET_CLASS, ":POPDOWN",
  812.        FTAB_Popup_Shell_Widget_Class_Method_POPDOWN);
  813.   xladdmsg(o_TRANSIENT_POPUP_SHELL_WIDGET_CLASS, ":ISNEW", 
  814.        FTAB_Popup_Shell_Widget_Class_Method_ISNEW);
  815.   xladdmsg(o_TRANSIENT_POPUP_SHELL_WIDGET_CLASS, ":REALIZE", 
  816.        FTAB_Shell_Widget_Class_Method_REALIZE);
  817.  
  818.   /*-------------------- XM_DIALOG_POPUP_SHELL_WIDGET_CLASS ------------------------*/
  819.   o_XM_DIALOG_POPUP_SHELL_WIDGET_CLASS =
  820.     Wcls_Create_Subclass_Of_WIDGET_CLASS("XM_DIALOG_POPUP_SHELL_WIDGET_CLASS",
  821.                      xmDialogShellWidgetClass);
  822.   xladdmsg(o_XM_DIALOG_POPUP_SHELL_WIDGET_CLASS, ":IS_MOTIF_WM_RUNNING", 
  823.        FTAB_Shell_Widget_Class_Method_IS_MOTIF_WM_RUNNING);
  824.   xladdmsg(o_XM_DIALOG_POPUP_SHELL_WIDGET_CLASS, ":UNREALIZE", 
  825.        FTAB_Shell_Widget_Class_Method_UNREALIZE);
  826.   xladdmsg(o_XM_DIALOG_POPUP_SHELL_WIDGET_CLASS, ":POPUP",
  827.        FTAB_Popup_Shell_Widget_Class_Method_POPUP);
  828.   xladdmsg(o_XM_DIALOG_POPUP_SHELL_WIDGET_CLASS, ":POPDOWN",
  829.        FTAB_Popup_Shell_Widget_Class_Method_POPDOWN);
  830.   xladdmsg(o_XM_DIALOG_POPUP_SHELL_WIDGET_CLASS, ":ISNEW", 
  831.        FTAB_Popup_Shell_Widget_Class_Method_ISNEW);
  832.   xladdmsg(o_XM_DIALOG_POPUP_SHELL_WIDGET_CLASS, ":REALIZE", 
  833.        FTAB_Shell_Widget_Class_Method_REALIZE);
  834.  
  835.   /*-------------------- XM_MENU_POPUP_SHELL_WIDGET_CLASS ------------------------*/
  836.   o_XM_MENU_POPUP_SHELL_WIDGET_CLASS =
  837.     Wcls_Create_Subclass_Of_WIDGET_CLASS("XM_MENU_POPUP_SHELL_WIDGET_CLASS",
  838.                      xmMenuShellWidgetClass);
  839.   xladdmsg(o_XM_MENU_POPUP_SHELL_WIDGET_CLASS, ":IS_MOTIF_WM_RUNNING", 
  840.        FTAB_Shell_Widget_Class_Method_IS_MOTIF_WM_RUNNING);
  841.   xladdmsg(o_XM_MENU_POPUP_SHELL_WIDGET_CLASS, ":UNREALIZE", 
  842.        FTAB_Shell_Widget_Class_Method_UNREALIZE);
  843.   xladdmsg(o_XM_MENU_POPUP_SHELL_WIDGET_CLASS, ":POPUP",
  844.        FTAB_Popup_Shell_Widget_Class_Method_POPUP);
  845.   xladdmsg(o_XM_MENU_POPUP_SHELL_WIDGET_CLASS, ":POPDOWN",
  846.        FTAB_Popup_Shell_Widget_Class_Method_POPDOWN);
  847.   xladdmsg(o_XM_MENU_POPUP_SHELL_WIDGET_CLASS, ":ISNEW", 
  848.        FTAB_Popup_Shell_Widget_Class_Method_ISNEW);
  849.   xladdmsg(o_XM_MENU_POPUP_SHELL_WIDGET_CLASS, ":REALIZE", 
  850.        FTAB_Shell_Widget_Class_Method_REALIZE);
  851. }
  852.